package cn.jarlen.jwt.tools.antivirus;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import java.util.ArrayList;
import java.util.List;


public class AntivirusDao {

    private final SQLiteDatabase database;
    private static AntivirusDao antivirus;

    public static AntivirusDao getInstance(Context context) {
        if (antivirus == null) {
            antivirus = new AntivirusDao(context);
        }
        return antivirus;
    }

    private AntivirusDao(Context context) {
        AntivirusDatabaseHelper helper = new AntivirusDatabaseHelper(context.getApplicationContext());
        this.database = helper.getWritableDatabase();
    }

    public List<CVELib> queryAndroidCVE() {
        StringBuffer buffer = new StringBuffer();
        buffer.append("SELECT * FROM ");
        buffer.append("PATCH");
        return queryAndroidCVE(buffer.toString(), null);
    }

    public List<CVELib> queryAllCVE(String filterOs) {
        StringBuffer buffer = new StringBuffer();
        buffer.append("SELECT * FROM ");
        buffer.append(CVELib.CVE_TABLE);
        buffer.append(" WHERE SYSTEM='" + filterOs + "'");

        Cursor cursor = this.database.rawQuery(buffer.toString(), null);
        List<CVELib> accountEntities = new ArrayList<>();
        try {
            if (cursor != null) {
                if (cursor.moveToFirst()) {
                    while (!cursor.isAfterLast()) {
                        CVELib cve = fillCVEEntity(cursor);
                        accountEntities.add(cve);
                        cursor.moveToNext();
                    }
                }
            }
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }
        return accountEntities;
    }

    public List<CVELib> queryAllCVE() {
        StringBuffer buffer = new StringBuffer();
        buffer.append("SELECT * FROM ");
        buffer.append(CVELib.CVE_TABLE);

        Cursor cursor = this.database.rawQuery(buffer.toString(), null);
        List<CVELib> accountEntities = new ArrayList<>();
        try {
            if (cursor != null) {
                if (cursor.moveToFirst()) {
                    while (!cursor.isAfterLast()) {
                        CVELib cve = fillCVEEntity(cursor);
                        accountEntities.add(cve);
                        cursor.moveToNext();
                    }
                }
            }
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }
        return accountEntities;
    }


    /**
     * 根据查询语句匹配的账户实体对象（集合）
     *
     * @param sql           查询语句
     * @param selectionArgs 查询参数
     * @return 账户实体对象（集合）
     */
    @Nullable
    public List<CVELib> queryAndroidCVE(@NonNull String sql, @Nullable String[] selectionArgs) {
        Cursor cursor = this.database.rawQuery(sql, selectionArgs);
        try {
            if (cursor != null) {
                if (cursor.moveToFirst()) {
                    List<CVELib> cveLibList = new ArrayList<>();
                    while (!cursor.isAfterLast()) {
                        CVELib cve = fillAntivirusEntity(cursor);
                        cveLibList.add(cve);
                        cursor.moveToNext();
                    }
                    return cveLibList;
                }
            }
            return null;
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }
    }

    public void insertAntivirus(List<CVELib> antivirusList) {
        if (antivirusList == null || antivirusList.isEmpty()) {
            return;
        }

        for (CVELib antivirus : antivirusList) {
            ContentValues contentValues = buildAntivirusContentValues(antivirus);
            database.insert(CVELib.CVE_TABLE, null, contentValues);
        }
    }

    /**
     * 重置漏洞库表
     */
    public void resetAllAntivirus() {
        StringBuffer buffer = new StringBuffer();
        buffer.append("drop table " + CVELib.CVE_TABLE);
        database.execSQL(buffer.toString());
        database.execSQL(CVELib.buffer.toString());
    }

    private CVELib fillCVEEntity(Cursor cursor) {
        CVELib antivirus = new CVELib();
        antivirus.setId(cursor.getLong(cursor.getColumnIndex("ID")));

        antivirus.setCve(cursor.getString(cursor.getColumnIndex("CVE")));
        antivirus.setCveLevel("" + cursor.getString(cursor.getColumnIndex("CVE_LEVEL")));
        antivirus.setCveDesc(cursor.getString(cursor.getColumnIndex("CVE_DESC")));
        antivirus.setPatchVer(cursor.getString(cursor.getColumnIndex("PATCH_VER")));

        antivirus.setAffectedVersion(cursor.getString(cursor.getColumnIndex("AFFECTED_VERSION")));
        antivirus.setSystem("" + cursor.getString(cursor.getColumnIndex("SYSTEM")));

        return antivirus;
    }


    @NonNull
    private CVELib fillAntivirusEntity(Cursor cursor) {
        CVELib antivirus = new CVELib();
        antivirus.setId(cursor.getLong(cursor.getColumnIndex("ID")));


        antivirus.setCve(cursor.getString(cursor.getColumnIndex("CVE")));
        antivirus.setCveLevel("" + cursor.getInt(cursor.getColumnIndex("CVE_LEVEL")));
        antivirus.setCveDesc(cursor.getString(cursor.getColumnIndex("CVE_DESC")));
        antivirus.setPatchVer(cursor.getString(cursor.getColumnIndex("SECURITY_PATCH_VER")));

        antivirus.setAffectedVersion(cursor.getString(cursor.getColumnIndex("AFFECTED_VERSION")));
        antivirus.setSystem("" + cursor.getInt(cursor.getColumnIndex("SYSTEM")));

        return antivirus;
    }

    /**
     * 构建账户ContentValues(不含账户ID)
     *
     * @param antivirus
     * @return
     */
    private ContentValues buildAntivirusContentValues(CVELib antivirus) {
        ContentValues contentValues = new ContentValues();
        contentValues.put("CVE", antivirus.getCve());
        contentValues.put("CVE_LEVEL", antivirus.getCveLevel());
        contentValues.put("CVE_DESC", antivirus.getCveDesc());
        contentValues.put("PATCH_VER", antivirus.getPatchVer());
        contentValues.put("AFFECTED_VERSION", antivirus.getAffectedVersion());
        contentValues.put("SYSTEM", antivirus.getSystem());
        return contentValues;
    }

}
